package com.mall_main.service;

import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder;
import com.common.pojo.MyUserDetails;
import com.common.result.JsonResult;

import com.common.result.ResultEnum;
import com.common.utils.SnowflakeIdGenerator;
import com.mall_main.cache.primaryRepository.MallRepository;
import com.mall_main.persist.mapper1.MallMapper;
import com.mall_main.pojo.cache.CountPriceCarCache;
import com.mall_main.pojo.cache.DeleteGoodsCache;
import com.mall_main.pojo.cache.SellerAddGoodsCache;
import com.mall_main.pojo.cache.AddShoppingCarCache;
import com.mall_main.pojo.dto.DeleteGoodsDTO;
import com.mall_main.pojo.dto.SellerAddGoodsDTO;
import com.mall_main.pojo.dto.ShoppingCarDTO;
import com.mall_main.pojo.po.OrderPO;
import javassist.compiler.TypeChecker;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.lang.reflect.Field;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

@Service
@Slf4j
public class MallService {
    @Autowired
    MallRepository mallRepository;

    @Autowired
    MallMapper mallMapper;

    @Value("${baking.workedId}")
    long workedId;
    @Value("${baking.datacenterId}")
    long datacenterId;

//
//    public  int  test1(){
//        int a=1;
//        return mallMapper.insertTest1(a);
//    }
//
//    public int test2(){
//        System.out.println("当前数据源：" + DynamicDataSourceContextHolder.peek());
//        int b=2;
//        return mallMapper.insertTest2(b);
//
//    }

    public JsonResult addUserShoppingCar(ShoppingCarDTO shoppingCarDTO) {

        return mallRepository.addShoppingCar(dto2Cache(shoppingCarDTO));


    }

    public AddShoppingCarCache dto2Cache(ShoppingCarDTO shoppingCarDTO) {
        AddShoppingCarCache addShoppingCarCache = new AddShoppingCarCache();
        BeanUtils.copyProperties(shoppingCarDTO, addShoppingCarCache);
        LocalDateTime localDateTime = LocalDateTime.now();
        addShoppingCarCache.setAddTime(localDateTime);
        return addShoppingCarCache;
    }

    public List<AddShoppingCarCache> getShoppingCar(long uid) {

        return mallRepository.getShoppingCar(uid);
    }

    public JsonResult deleteGoods(long uid, List<DeleteGoodsDTO> deleteGoodsDTOS) {
        List<DeleteGoodsCache> deleteGoodsCaches = new ArrayList<>();

        for (DeleteGoodsDTO deleteGoodsDTO : deleteGoodsDTOS) {
            DeleteGoodsCache deleteGoodsCache = new DeleteGoodsCache();
            BeanUtils.copyProperties(deleteGoodsDTO, deleteGoodsCache);
            deleteGoodsCaches.add(deleteGoodsCache);
        }

        List<AddShoppingCarCache> shoppingCar = mallRepository.getShoppingCar(uid);
        if (shoppingCar == null) {
            return new JsonResult(48001, "购物车为空，无需删除");

        } else {
            int result = mallRepository.deleteGoods(uid, deleteGoodsCaches);
            return new JsonResult(48002, "成功删除" + result + "件商品");

        }

    }

    public JsonResult sellerAddGoods(SellerAddGoodsDTO sellerAddGoodsDTO) {
        SellerAddGoodsCache sellerAddGoodsCache = new SellerAddGoodsCache();
        BeanUtils.copyProperties(sellerAddGoodsDTO, sellerAddGoodsCache);
        SnowflakeIdGenerator generator = new SnowflakeIdGenerator(1, 1);
        long gid = generator.nextId();
        sellerAddGoodsCache.setGid(gid);
        Boolean result = mallRepository.SellerAddGoods(sellerAddGoodsCache);
        if (result == true) {
            return new JsonResult(200, "成功添加一件商品");
        } else if (result == false) {
            return new JsonResult(ResultEnum.SELLER_ADD_GOODS_FAILED);
        } else {
            return new JsonResult(ResultEnum.MALL_UNKNOWN_ERROR);
        }

    }

    @Transactional
    public JsonResult createOrder(List<ShoppingCarDTO> shoppingCarDTOS) throws NoSuchFieldException {
        Object details = SecurityContextHolder.getContext().getAuthentication().getDetails();
        Field field = TypeChecker.class.getDeclaredField("details");
        if (field.getType() != long.class) {
            log.info("security上下文获取用户身份出了问题，details里存的并不是Uid");
            return new JsonResult(ResultEnum.ERROR_UNKNOWN);
        } else {
            MyUserDetails userDetails = (MyUserDetails) details;
            long uid = userDetails.getUid();
            String receiveInfo = userDetails.getReceive_info();
            int totalPrice = 0;
            HashMap<Long, Integer> goods = new HashMap<>();

            for (ShoppingCarDTO shoppingCarDTO : shoppingCarDTOS) {
                long gid = shoppingCarDTO.getGid();
                int number = shoppingCarDTO.getNumber();
                goods.put(gid, number);
                CountPriceCarCache countPriceCarCache = carDTO2Cache(shoppingCarDTO);
                int price = mallRepository.getPrice(countPriceCarCache);
                totalPrice = totalPrice + price;
            }

            SnowflakeIdGenerator snowflakeIdGenerator = new SnowflakeIdGenerator(workedId, datacenterId);
            long oid = snowflakeIdGenerator.nextId();


            OrderPO orderPO = new OrderPO();
            orderPO.setOid(oid);
            orderPO.setUid(uid);
            orderPO.setGoods(goods);
            orderPO.setCreateTime(LocalDateTime.now());
            orderPO.setTotalPrice(totalPrice);
            orderPO.setReceiveInfo(receiveInfo);

            int result = mallMapper.createOrder(orderPO);


            if (result == 1) {
                List<DeleteGoodsDTO> deleteGoodsDTOS = carDTO2deleteDTO(shoppingCarDTOS);
                JsonResult jsonResult = deleteGoods(uid, deleteGoodsDTOS);
                return jsonResult;

            } else {
                return new JsonResult(ResultEnum.CREATE_ORDER_FAILED);

            }
        }


    }

    public CountPriceCarCache carDTO2Cache(ShoppingCarDTO shoppingCarDTO) {
        CountPriceCarCache countPriceCarCache = new CountPriceCarCache();
        BeanUtils.copyProperties(shoppingCarDTO, countPriceCarCache);
        return countPriceCarCache;

    }

    public List<DeleteGoodsDTO> carDTO2deleteDTO(List<ShoppingCarDTO> shoppingCarDTOS) {
        List<DeleteGoodsDTO> deleteGoodsDTOS = new ArrayList<>();

        for (ShoppingCarDTO shoppingCarDTO : shoppingCarDTOS) {
            DeleteGoodsDTO deleteGoodsDTO = new DeleteGoodsDTO();

            BeanUtils.copyProperties(shoppingCarDTO, deleteGoodsDTO);
            deleteGoodsDTOS.add(deleteGoodsDTO);

        }
        return deleteGoodsDTOS;


    }


}
